home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.09 Sep 96 / C++ DebugStr / debugbuf.cp next >
Encoding:
Text File  |  1996-06-18  |  3.0 KB  |  209 lines  |  [TEXT/R*ch]

  1. // (c) copyright 1995,1996, Jon Kalb, Liberty Software
  2. // Kalb@LibertySoft.com
  3. // You may freely incorporate this code into any machine-
  4. // readable project. You may modify this code, but you may
  5. // not remove this statement. 
  6.  
  7. #include "doutstream"
  8.  
  9. #include <string.h>    // for strlen() and strcpy()
  10. #include <OSUtils.h>    // for SysBeep();
  11.  
  12. static debugbuf debugstream;
  13. ostream dout(&debugstream);
  14.  
  15. unsigned int debugbufinit::count = 0;
  16.  
  17. // this is debug code -- performance is not a goal
  18.  
  19. void debugbuf::init() // called by friend class debugbufinit
  20. {
  21.     pbeg[0] = '\0';
  22.     pnext = pbeg + kSizeOfLengthByte;
  23.     pend = pnext + kMaxDebugStrReadableString;
  24.     alertCount = 0;
  25. }
  26.  
  27.  
  28. int debugbuf::overflow(int c)
  29. {
  30.     if (EOF == c)
  31.     {
  32.         return '\0';    // returning EOF indicates an error
  33.     }
  34.     else
  35.     {
  36.         outputchar(c);
  37.         return c;
  38.     }
  39. }
  40.  
  41.  
  42. int debugbuf::xsputn(const char *s, int n)
  43. {
  44.     for (int i = 0; i < n; ++i)
  45.     {
  46.         outputchar(s[i]);
  47.     }
  48.     return n;    // we always process all of the chars
  49. }
  50.  
  51.  
  52. void debugbuf::outputchar(char c)
  53. {
  54.     switch (c)
  55.     {
  56.         case '\b':
  57.             backspace();
  58.             break;
  59.         case '\f':
  60.             formfeed();
  61.             break;
  62.         case '\n':
  63.             flushdebugstring();
  64.             break;
  65.         case '\r':
  66.             softflush();
  67.             break;
  68.         case '\t':
  69.             horztab();
  70.             break;
  71.         case '\v':
  72.             verttab();
  73.             break;
  74.         case '\a':
  75.             alert();
  76.             break;
  77.         case '\0':
  78.         case '\x03':
  79.             flushdebugstring(kStop);
  80.             break;
  81.         default:
  82.             addchar(c);
  83.             break;
  84.     }
  85. }
  86.  
  87.  
  88. void debugbuf::backspace()
  89. {
  90.     if (pbeg[0])    // if the buffer is empty, don't bother
  91.     {
  92.         --pnext; 
  93.         --pbeg[0];
  94.     }
  95.     // note that alerts cannot be backspaced away -- a
  96.     // possible enhancement
  97. }
  98.  
  99.  
  100. void debugbuf::formfeed()
  101. {
  102.     softflush();
  103.     strcpy(pbeg, (char *)
  104.         "\p_______________________________________________");
  105.     pnext += strlen(pnext);
  106.     flushdebugstring();
  107. }
  108.  
  109.  
  110. // both horizontal and verticle tabbing is done by brute
  111. // force -- performance is not a goal
  112. void debugbuf::horztab()
  113. {
  114.     // we don't wrap tabs so if we are within kTabSize of
  115.     // the end of the buffer then we just flush
  116.     if (pend - pnext <= kTabSize)
  117.     {
  118.         flushdebugstring();
  119.     }
  120.     else
  121.     {
  122.         for (int i = 0; i < kTabSize; ++i)
  123.         {
  124.             addchar(' ');
  125.         }
  126.     }
  127. }
  128.  
  129.  
  130. void debugbuf::verttab()
  131. {
  132.     int position = pnext - &pbeg[1];
  133.     flushdebugstring();
  134.     for (int i = 0; i < position; ++i)
  135.     {
  136.         addchar(' ');
  137.     }
  138. }
  139.  
  140.  
  141. void debugbuf::alert()
  142. {
  143.     ++alertCount;
  144. }
  145.  
  146.  
  147. void debugbuf::addchar(char c)
  148. {
  149.     *pnext++ = c;
  150.     ++pbeg[0];
  151.     if (pnext == pend)
  152.     {
  153.         flushdebugstring();
  154.     }
  155. }
  156.  
  157.  
  158. void debugbuf::softflush()
  159. {
  160.     if ('\0' != pbeg[0])
  161.     {
  162.         flushdebugstring();
  163.     }
  164.     else
  165.     {
  166.         flushalerts();
  167.     }
  168. }
  169.  
  170. void debugbuf::flushalerts()
  171. {
  172.     while (alertCount)
  173.     {
  174.         --alertCount;
  175.         SysBeep(30);
  176.     }
  177. }
  178.  
  179. void debugbuf::flushdebugstring(int stop)
  180. {
  181.     if (!stop)
  182.     {
  183.         addchar(';');
  184.         addchar('g');
  185.     }
  186.     flushalerts();
  187.     DebugStr((unsigned char *)pbeg);
  188.     pbeg[0] = '\0';
  189.     pnext = &pbeg[1];
  190. }
  191.  
  192.  
  193. debugbufinit::debugbufinit()
  194. {
  195.     if (0 == count++)
  196.     {
  197.         debugstream.init();
  198.     }
  199. }
  200.  
  201. debugbufinit::~debugbufinit()
  202. {
  203.     if (0 == --count)
  204.     {
  205.         // nothing to dispose, but we should flush
  206.         debugstream.softflush();
  207.     }
  208. }
  209.